//
//  AKRequestManager.m
//  CocoaBean
//
//  Created by sleeper on 5/20/10.
//  Copyright 2010 __MyCompany__ All rights reserved.
//

#import "GDataOAuthAuthentication.h"
#import "NSString+URLEncoding.h"

#import "AKRequest_Private.h"
#import "AKRequestManager.h"

@interface AKRequestManager () <AKRequestDelegate>
@end

@implementation AKRequestManager

- (id)initWithAuthentication:(GDataOAuthAuthentication *)auth
{
	if ((self = [super init])) {
		_queue = [[NSOperationQueue alloc] init];
		_auth = [auth retain];
		_delegateLookUp = AKCreateNonRetainingDictionary();
	}
	return self;
}

- (void)dealloc
{
	AK_RELEASE(_queue);
	AK_RELEASE(_auth);
	AK_RELEASE(_delegateLookUp);
	[super dealloc];
}

- (void)runRequest:(AKRequest*)request delegate:(id <AKRequestDelegate>)aDelegate
{
	[self runRequest:request delegate:aDelegate cancelRequestsWithSameType:NO];
}

- (void)runRequest:(AKRequest*)request delegate:(id <AKRequestDelegate>)aDelegate cancelRequestsWithSameType:(BOOL)flag
{
	if (flag) {
		NSArray *allOperations = [_queue operations];
		for (AKRequest *aRequest in allOperations) {
			if ([aRequest.type isEqualToString:request.type]) {
				[aRequest cancel];
			}
		}
	}
	
	request.authentication = _auth;
	request.delegate = self;
	
	[_delegateLookUp setObject:aDelegate forKey:request.uuid];
	
	[request addObserver:self forKeyPath:@"isFinished" options:0 context:NULL];
	
	[_queue addOperation:request];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
	if ([keyPath isEqualToString:@"isFinished"]) {
		AKRequest *request = (AKRequest *)object;
		if ([request isFinished]) {
			[request removeObserver:self forKeyPath:@"isFinished"];
			[_delegateLookUp removeObjectForKey:request.uuid];
		}
	}
}

#pragma mark AKRequestDelegate

- (void)request:(AKRequest *)request didFinishWithData:(NSData *)data
{
	id <AKRequestDelegate> delegate = [_delegateLookUp objectForKey:request.uuid];
	if (delegate) {
		[delegate request:request didFinishWithData:data];
		[_delegateLookUp removeObjectForKey:request.uuid];
	}
}

- (void)request:(AKRequest *)request didFailWithError:(NSError *)error
{
	id <AKRequestDelegate> delegate = [_delegateLookUp objectForKey:request.uuid];
	if (delegate) {
		[delegate request:request didFailWithError:error];
		[_delegateLookUp removeObjectForKey:request.uuid];
	}
}

- (BOOL)removeDelegate:(id <AKRequestDelegate>)aDelegate
{
	BOOL removed = NO;
	for (id key in [_delegateLookUp allKeys]) {
		if ([_delegateLookUp objectForKey:key] == aDelegate) {
			[_delegateLookUp removeObjectForKey:key];
			removed = YES;
		}
	}
	return removed;
}

@end
